package com.chj.Sender;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.chj.config.RabbitConfig;
import com.chj.constant.Rabbit;
import com.rabbitmq.client.MessageProperties;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.context.annotation.Scope;
import org.springframework.lang.Nullable;
import org.springframework.stereotype.Component;

import java.util.Date;

@Component
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public class RabbitConfirmSender implements RabbitTemplate.ConfirmCallback, RabbitTemplate.ReturnCallback {
	private static final Logger logger = LoggerFactory.getLogger(RabbitConfirmSender.class);

	private RabbitTemplate rabbitTemplate;
	
	public RabbitTemplate getRabbitTemplate(){
		return rabbitTemplate;
	}
	
	@Autowired
	public RabbitConfirmSender(RabbitTemplate rabbitTemplate){
		rabbitTemplate.setConfirmCallback(this);
		rabbitTemplate.setReturnCallback(this);
		this.rabbitTemplate = rabbitTemplate;
	}
	
	/**
	 * 
	 * @param json : 包括 exchange, routingKey, msg 
	 */
	public void send(JSONObject json){
		try{
			CorrelationData correlationData = RabbitConfig.correlationData();
			if (StringUtils.isBlank(json.getString(Rabbit.JsonKey.UUID))){
				json.put(Rabbit.JsonKey.UUID, correlationData.getId());
			}
			json.put(Rabbit.JsonKey.CREATE_DATE, new Date());
			logger.debug("消息发送开始 {} {}", correlationData.getId(), json);
			rabbitTemplate.convertAndSend(json.getString(Rabbit.JsonKey.EXCHANGE), json.getString(Rabbit.JsonKey.ROUTING_KEY), json.toJSONString(), correlationData);
			logger.debug("消息发送结束 {}", correlationData.getId());
		} catch(Exception e){
			logger.error("消息发送失败{} error {}", json, e);
		}
	}
	
	/**
	 * 
	 * @param exchange
	 * @param routingKey
	 * @param msg ： 转换为JSON对象，如果是JSONArray则转换为{Rabbit.JsonKey.MESSAGE_ARRAY:jsonArray}格式的JSONObject对象
	 */
	public void send(String exchange, String routingKey, Object msg){
		try{
			CorrelationData correlationData = RabbitConfig.correlationData();
			JSON tmp = (JSON)JSONObject.toJSON(msg);
			JSONObject json = new JSONObject();
			if (StringUtils.isBlank(json.getString(Rabbit.JsonKey.UUID))){
				json.put(Rabbit.JsonKey.UUID, correlationData.getId());
			}
			json.put(Rabbit.JsonKey.EXCHANGE, exchange);
			json.put(Rabbit.JsonKey.ROUTING_KEY, routingKey);
			json.put(Rabbit.JsonKey.CREATE_DATE, new Date());
			json.put(Rabbit.JsonKey.MESSAGE, tmp);
			logger.debug("消息发送开始 {} {}", correlationData.getId(), json);
			rabbitTemplate.convertAndSend(exchange, routingKey, json.toJSONString(), correlationData);
			logger.debug("消息发送结束 {}", correlationData.getId());
		} catch(Exception e){
			logger.error("发送消息失败：{} {} {} {}", exchange, routingKey, JSONObject.toJSONString(msg), e);
			e.printStackTrace();
		}
	}


	@Override
	public void returnedMessage(Message message, int replyCode,
                                String replyText, String exchange, String routingKey) {
		JSONObject json = RabbitConfig.messageBody(message);
		json.put(Rabbit.JsonKey.REPLY_TEXT, replyText);
		json.put(Rabbit.JsonKey.REPLY_CODE, replyCode);
		logger.error("消息路由异常: {} {} {} ", exchange, routingKey, json);
		// 默认转发到异常消息队列
		send(Rabbit.WrongLetter.EX_WRONG_LETTER, Rabbit.WrongLetter.RK_WRONG_LETTER, json);
	}

	@Override
	public void confirm(@Nullable CorrelationData correlationData, boolean ack, @Nullable String cause) {
		if (correlationData == null){
			correlationData = new CorrelationData();
		}
		if (ack) {
			logger.debug("消息发送成功 {}", correlationData.getId());
		} else {
			logger.error("消息发送异常 {} {} {}", correlationData.getId(), ack, cause);
		}
	}


}
